package com.weipai.springboot.module.service.impl;

import com.weipai.springboot.base.interceptor.LoginHandlerInterceptor;
import com.weipai.springboot.base.interceptor.MyAuthenticationFilter;
import com.weipai.springboot.enums.RetCode;
import com.weipai.springboot.model.*;
import com.weipai.springboot.model.api.Response;
import com.weipai.springboot.model.sys.User;
import com.weipai.springboot.module.dao.AdminDao;
import com.weipai.springboot.module.dao.ArtisanDao;
import com.weipai.springboot.module.dao.CustomerDao;
import com.weipai.springboot.module.dao.ShopDao;
import com.weipai.springboot.module.service.RoleService;
import com.weipai.springboot.module.mapper.CustomerMapper;
import com.weipai.springboot.module.service.UserService;
import com.weipai.springboot.module.util.SessionUserUtil;
import com.weipai.springboot.module.util.wxPayUtil.HttpRequest;
import com.weipai.springboot.shiro.AppCacheDao;
import com.weipai.springboot.util.PasswordHelper;
import com.weipai.springboot.util.PropUtils;
import com.weipai.springboot.util.WxPayMessage;
import com.weipai.springboot.util.unionSdk.LogUtil;
import net.sf.json.JSONObject;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.List;
import java.util.Vector;

/**
 * @author songmengqiang
 * @create 2018-08-29 19:00
 **/
@Service
public class UserServiceImpl implements UserService {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    private static int TIME_OUT = 3600 * 24 * 30;

    @Autowired
    private AdminDao adminDao;
    @Autowired
    private CustomerDao customerDao;
    @Autowired
    private ShopDao shopDao;
    @Autowired
    private ArtisanDao artisanDao;
    @Autowired
    private AppCacheDao appCacheDao;
    @Autowired
    private SessionUserUtil sessionUserUtil;
    @Autowired
    private RoleService roleService;
    @Autowired
    CustomerMapper customerMapper;

    //登录
    @Override
    public Response login(String username, String password, String code) {
        LogUtil.writeLog("打印请求HTML，此为请求报文，为联调排查问题的依据：" + code);
        Response response = new Response();
        int type = sessionUserUtil.getUserType();
        logger.info("into login username:{} type: {}", username, type);
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        User user = null;
        Serializable id1 = null;
//        User user = sessionUserUtil.getUser();
//        if (user != null) {
//            response.put("user", user.getUser());
//            response.setCode(RetCode.SUCCESS);
//            return response;
//        }
        try {
            Subject subject = SecurityUtils.getSubject();
            subject.login(token);
            if (User.CUSTOMER == type) {
                user = getCustomerUser(username);
                logger.info("user:"+ com.alibaba.fastjson.JSONObject.toJSONString(user));
                Customer customer = user.getUser();


                if (-1 == customer.getCustomerStatus()) {
                    response.setCode(RetCode.FORBIDDEN);
                    return response;
                }

                if(!StringUtils.isEmpty(password)){
                    String s = PasswordHelper.encryptPassword(password, username);
                    if(!s.equals(customer.getCustomerPassword())){
                        response.setCode(RetCode.PASSWORD_NOT_SAME);
                        response.setMsg(RetCode.PASSWORD_NOT_SAME.getMsg() );
                        return response;
                    }
                }


                if (code != null && !"".equals(code)) {
                    logger.info("进入：-------------------------------------------------",code);
                    WxPayMessage wxPayMessage = new WxPayMessage();
                    //页面获取openId接口
                    String getopenid_url = "https://api.weixin.qq.com/sns/oauth2/access_token";
                    String param = "appid=" + wxPayMessage.getAppId() + "&secret=" + wxPayMessage.getSecret() + "&code=" + code + "&grant_type=authorization_code";
                    //向微信服务器发送get请求获取openIdStr
                    String openIdStr = HttpRequest.sendGet(getopenid_url, param);
                    logger.info("openIdStr：-------------------------"+openIdStr);
                    JSONObject json = JSONObject.fromObject(openIdStr);//转成Json格式
                    String openId = json.getString("openid");//获取openId
                    logger.info("openId：-------------------------"+openId);
                    customerMapper.updateByOppenID(openId, customer.getCustomerId());
                }
                int expire = (int) (System.currentTimeMillis() / 1000 + TIME_OUT);

                String authToken = PasswordHelper.generateToken(username, expire, PropUtils.getString("system.secretKey"));
                logger.info("system.secretKey:"+PropUtils.getString("system.secretKey"));
                appCacheDao.save(authToken, user);
                response.put(LoginHandlerInterceptor.AUTH_TOKEN_HEADER, authToken);
            } else {
                Session session = subject.getSession();
                Admin admin = adminDao.getAdminByLoginName(username);
                if(!StringUtils.isEmpty(password)){
                    String s = PasswordHelper.encryptPassword(password, username);
                    if(!s.equals(admin.getAdminPassword())){
                        response.setCode(RetCode.PASSWORD_NOT_SAME);
                        response.setMsg(RetCode.PASSWORD_NOT_SAME.getMsg() );
                        return response;
                    }
                }
                Role role = roleService.getRoleObject((long) Integer.parseInt(admin.getRoleId()));
                if (null != role) {
                    response.put("roleName", role.getRoleName());
                } else {
                    logger.info("no admin roleId:{}", admin.getAdminLoginName());
                }
                user = new User(User.EMPLOYEE, admin);
                session.setAttribute(User.KEY, user);
                id1 = session.getId();
            }
            MyAuthenticationFilter.sessionid=id1+"";
            response.setSessionId(id1);
            response.put("user", user.getUser());
            response.setCode(RetCode.SUCCESS);
        } catch (IncorrectCredentialsException e) {
            e.printStackTrace();
            logger.error("login error = {}", e.getMessage());
            //密码错误
            response.setCode(RetCode.PWD_ERROR);
        } catch (AuthenticationException e) {
            e.printStackTrace();
            response.setCode(RetCode.LOGIN_FAIL);
            logger.error("login error = {}", e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("login error = {}", e.getMessage());
            response.setCode(RetCode.LOGIN_FAIL);
        }

        return response;
    }

    //微信第三方登录
    @Override
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED)
    public Response thirdPartyLogin(Customer customer) {
        Response response = new Response();
        //通过登录名 查询 用户
        Customer customer3 = customerMapper.getCustomerByLoginName(customer.getCustomerLoginName());
        //查询此微信 id 是否 绑定账号
        Customer customer2 = customerMapper.selectByWxUid(customer.getWxUid());

        //判断是否绑定  直接登录
        if (customer2 != null) {                                    //已注册, 绑定过微信
            int type = sessionUserUtil.getUserType();
            User user = null;
            Subject subject = SecurityUtils.getSubject();
            if (User.CUSTOMER == type) {
                user = getCustomerUser(customer2.getCustomerLoginName());
                int expire = (int) (System.currentTimeMillis() / 1000 + TIME_OUT);
                String authToken = PasswordHelper.generateToken(customer2.getCustomerLoginName(), expire, PropUtils.getString("system.secretKey"));
                appCacheDao.save(authToken, user);
                response.put(LoginHandlerInterceptor.AUTH_TOKEN_HEADER, authToken);
            } else {
                Session session = subject.getSession();
                Admin admin = adminDao.getAdminByLoginName(customer2.getCustomerLoginName());
                user = new User(User.EMPLOYEE, admin);
                session.setAttribute(User.KEY, user);
            }
            response.put("customer", user.getUser());
            response.setCode(RetCode.SUCCESS);
        } else if (customer3 != null && customer2 == null) {          //注册过,未绑定微信,去绑定
            response.setCode(RetCode.BOUND_NO);
            //原密码
            String customerPassword = customer3.getCustomerPassword();
            //新输入密码
            String newPassword = PasswordHelper.encryptPassword(customer.getCustomerPassword(), customer.getCustomerLoginName()); //密码加盐
            if (customer.getWxUid() != null && customer.getWxUid() != "") {
                if (!customerPassword.equals(newPassword)) {
                    response.setCode(RetCode.PWD_ERROR);
                } else {
                    customer3.setWxUid(customer.getWxUid());
                    if (1 == customerMapper.updateByPrimaryKeySelective(customer3)) {
                        response.setCode(RetCode.BOUND_SUCCESS);   //绑定成功
                    } else {
                        response.setCode(RetCode.BOUND_FAIL);  //绑定失败
                    }
                }
            } else {
                response.setCode(RetCode.BOUND_FAIL);
            }
        } else if (customer3 == null && customer2 == null) {                                   //未注册过,去注册
            response.setCode(RetCode.ZHUCE_NO);
        }

        return response;
    }

    @Override
    public Response verifyCustomer(String username) {
        Response response = new Response();
        Customer customer = customerDao.getCustomerByLoginName(username);
        if (null != customer) {
            if (customer.getCustomerStatus() == -1) {
                response.setCode(RetCode.FORBIDDEN);
            } else {
                response.setCode(RetCode.SUCCESS);
            }
        } else {
            response.setCode(RetCode.NOT_LOGIN);
        }
        return response;
    }


    @Override
    public User getCustomerUser(String username) {
        Customer customer = customerDao.getCustomerByLoginName(username);
        if (customer == null) {
            return null;
        }
        User user = new User(User.EMPLOYEE, customer);
        //细分：技工、商家
        Shop shop = shopDao.getShopByCustomerId(customer.getCustomerId());
        if (null != shop) {
            user.setShop(shop);
        }
        Artisan artisan = artisanDao.getArtisanByCustomerId(customer.getCustomerId());
        if (null != artisan) {
            user.setArtisan(artisan);
        }

        //推荐码
        Admin admin = adminDao.getAdminByCustomerId(customer.getCustomerId());
        if (admin != null) {
            user.put("admin_code", admin.getAdminCode());
        }
        return user;
    }

    //管理员重置密码
    @Override
    public Response resetAdminPassword(String adminId, String oldPassword, String newPassword, String twoPassword) {
        Response response = new Response();
        //判断两次密码是否一样
        if (!newPassword.equals(twoPassword)) {
            response.setCode(RetCode.PASSWORD_NOT_SAME);
        } else {
            if (null == adminId) {
                adminId = sessionUserUtil.getAdminAttr().getAdminId();
            }
            Admin admin = adminDao.getAdminById(adminId);
            admin.setAdminPassword(PasswordHelper.encryptPassword(twoPassword, admin.getAdminLoginName()));
            if (1 == adminDao.updateByPrimaryKey22(admin)) {
                response.setCode(RetCode.SUCCESS);
            } else {
                response.setCode(RetCode.REQUEST_ERROR);
            }
        }
        return response;
    }


    @Override
    public Response loginOut() {
        Response response = new Response();
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        User user = (User) subject.getSession().getAttribute(User.KEY);
        logger.info("user {}", user);
        response.setCode(RetCode.SUCCESS);
        return response;
    }

}
